package com.atguigu.tingshu.order.service.impl;

import com.alibaba.fastjson.JSON;
import com.atguigu.tingshu.common.constant.KafkaConstant;
import com.atguigu.tingshu.common.constant.SystemConstant;
import com.atguigu.tingshu.common.service.KafkaService;
import com.atguigu.tingshu.common.util.AuthContextHolder;
import com.atguigu.tingshu.model.order.OrderDetail;
import com.atguigu.tingshu.model.order.OrderInfo;
import com.atguigu.tingshu.order.context.OrderHandlerInterceptorContext;
import com.atguigu.tingshu.order.context.OrderTradeStrategyContext;
import com.atguigu.tingshu.order.enumeration.OrderStatusEnum;
import com.atguigu.tingshu.order.enumeration.PayWayEnum;
import com.atguigu.tingshu.order.mapper.OrderInfoMapper;
import com.atguigu.tingshu.order.service.OrderDetailService;
import com.atguigu.tingshu.order.service.OrderInfoService;
import com.atguigu.tingshu.order.strategy.OrderTradeStrategy;
import com.atguigu.tingshu.vo.order.OrderInfoVo;
import com.atguigu.tingshu.vo.order.TradeVo;
import com.atguigu.tingshu.vo.user.UserPaidRecordVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
@SuppressWarnings({"unchecked", "rawtypes"})
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements OrderInfoService {

	@Autowired
	private OrderInfoMapper orderInfoMapper;
	@Autowired
	private OrderDetailService orderDetailService;
	@Autowired
	private KafkaService kafkaService;


	@Override
	public OrderInfoVo trade(TradeVo tradeVo) {
		/*
		 * 策略设计模式
		 * 1.OrderTradeStrategy  顶层接口,设置规范,
		 * 2.OrderTradeStrategy 的实现类
		 * 			AlbumOrderTradeStrategy		负责实现各种业务逻辑,并交给容器管理,提供一个身份辨别的方法
		 * 			TrackOrderTradeStrategy
		 * 			VipOrderTradeStrategy
		 * 3.OrderTradeStrategyContext 管理类,获取对应方法的乳沟
		 * 3.1 设置一个 ConcurrentHashMap<String,OrderTradeStrategy> 集合
		 * 3.2 实现 ApplicationContextAware 接口,获取上下文,根据 OrderTradeStrategy 类型,维护进 Map 集合里面
		 * 3.3 提供一个获取函数的入口,根据值从 Map 集合中获取对应的方法
		 * 3.4 调用方法并返回结果
		 */
		OrderTradeStrategy orderTradeStrategy = OrderTradeStrategyContext.getOrderTradeStrategy(tradeVo.getItemType());
		return orderTradeStrategy.trade(tradeVo);
	}

	@Override
	public String submitOrder(OrderInfoVo orderInfoVo) {
		// 1.校验数据是否被篡改 ValidDataOrderHandlerInterceptor
		// 2.校验订单是否重复 OrderRepeatSubmitValidOrderHandlerInterceptor
		// 3.保存订单到本地 SavaOrderOrderHandlerInterceptor
		// 三个任务有顺序,可以使用责任链模式  OrderHandlerInterceptor
		// 订单管理类 OrderHandlerInterceptorContext
		OrderInfoVo result = OrderHandlerInterceptorContext.entry(orderInfoVo);
		return result.getTradeNo();
	}

	@Override
	public void orderPaySuccess(String orderNo) {
		// 修改状态
		this.updateOrderStatus(orderNo, SystemConstant.ORDER_STATUS_PAID);
		// 	 构建支付记录对象
		OrderInfo orderInfo = this.getOrderInfoByOrderNo(orderNo);
		UserPaidRecordVo userPaidRecordVo = new UserPaidRecordVo();
		userPaidRecordVo.setOrderNo(orderNo);
		userPaidRecordVo.setUserId(orderInfo.getUserId());
		userPaidRecordVo.setItemType(orderInfo.getItemType());
		userPaidRecordVo.setItemIdList(orderInfo.getOrderDetailList()
				.stream()
				.map(OrderDetail::getItemId)
				.collect(Collectors.toList()));
		// 	KafKa  (UserPaidRecordVo),(tingshu.user.pay.record)
		kafkaService.sendMsg(KafkaConstant.QUEUE_USER_PAY_RECORD, JSON.toJSONString(userPaidRecordVo));
		log.info("发送保存交易数据消息成功....");
	}

	@Override
	public void updateOrderStatus(String orderNo, String orderStatus) {
		OrderInfo orderInfo = this.getOne(new LambdaQueryWrapper<OrderInfo>().eq(OrderInfo::getOrderNo, orderNo));
		orderInfo.setOrderStatus(orderStatus);
		this.updateById(orderInfo);
	}

	@Override
	public OrderInfo getOrderInfoByOrderNo(String orderNo) {
		OrderInfo orderInfo = this.getOne(new LambdaQueryWrapper<OrderInfo>().eq(OrderInfo::getOrderNo, orderNo));
		orderInfo.setOrderDetailList(orderDetailService
				.list(new LambdaQueryWrapper<OrderDetail>()
						.eq(OrderDetail::getOrderId, orderInfo.getId())));
		// 设置订单状态
		orderInfo.setOrderStatus(OrderStatusEnum.getOrderStatusEnum(orderInfo.getOrderStatus()));

		// 设置支付方式
		orderInfo.setPayWayName(PayWayEnum.getPayWayName(orderInfo.getPayWay()));
		return orderInfo;
	}

	@Override
	public OrderInfo getOrderInfo(String orderNo) {
		Long userId = AuthContextHolder.getUserId();
		return orderInfoMapper.selectOne(new LambdaQueryWrapper<OrderInfo>()
				.eq(OrderInfo::getOrderNo,orderNo)
				.eq(OrderInfo::getUserId,userId));
	}

	@Override
	public IPage<OrderInfo> findUserPage(Integer pageNo, Integer pageSize) {
		IPage<OrderInfo> page = new Page<>(pageNo,pageSize);
		page = this.page(page, new LambdaQueryWrapper<OrderInfo>().eq(OrderInfo::getUserId, AuthContextHolder.getUserId()).orderByDesc(OrderInfo::getUpdateTime));
		List<OrderInfo> records = page.getRecords();
		records.forEach(orderInfo -> {
			orderInfo.setOrderDetailList(orderDetailService.list(new LambdaQueryWrapper<OrderDetail>().eq(OrderDetail::getOrderId,orderInfo.getId())));
		});
		return page;
	}
}
